﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Windows.Forms;

namespace MinotaurPathfinder
{
    public partial class Map : Form
    {
        Pathfinder _pathfinder = new Pathfinder();

        public Map()
        {
            /*
             * 
             * Do initializations and events.
             * 
             * */
            this.Font = SystemFonts.MessageBoxFont;
            InitializeComponent();

            boardControl1.MouseClick += new MouseEventHandler(boardControl1_MouseClick);
            boardControl1.MouseMoveSpecial += new EventHandler(boardControl1_MouseMoveSpecial);
            toolStripStatusLabel1.Text = "";
        }

        void boardControl1_MouseMoveSpecial(object sender, EventArgs e)
        {
            /*
             * 
             * Called when the mouse moves to a different square.
             * 
             * */
            Point point = boardControl1.Pos;
            if (point.X == -1 || point.Y == -1)
            {
                return;
            }
            int count = _pathfinder.Squares[point.X, point.Y].DistanceSteps;
            if (count == Pathfinder.bigNumber)
            {
                toolStripStatusLabel1.Text = "Impossible";
            }
            else if (count == 1)
            {
                toolStripStatusLabel1.Text = "1 step";
            }
            else if (count == 0)
            {
                toolStripStatusLabel1.Text = "Current";
            }
            else
            {
                toolStripStatusLabel1.Text = count.ToString() + " steps.";
            }
            toolStripStatusLabel1.Text += " X:" + point.X.ToString() + " Y:" + point.Y.ToString();
        }

        void boardControl1_MouseClick(object sender, MouseEventArgs e)
        {
            int vehicleID;
            vehicleID = Convert.ToInt32(tbAracKodu.Text);

            Point point = boardControl1.Pos;

            if (point.X == -1 || point.Y == -1)
            {
                return;
            }

            if (e.Button == MouseButtons.Right)
            {
                /*
                 * 
                 * Reposition the monster to the point clicked.
                 * 
                 * */
                for (int row = 0; row < Pathfinder.gridSizeY; row++)
                {
                    for (int col = 0; col < Pathfinder.gridSizeX; col++)
                    {
                        if (_pathfinder.Squares[col, row].ContentCode == SquareContent.FinishLocation(vehicleID))
                        {
                            _pathfinder.Squares[col, row].ContentCode = SquareContent.Empty;
                            break;
                        }
                    }
                }
                _pathfinder.Squares[point.X, point.Y].ContentCode = SquareContent.FinishLocation(vehicleID);

                Recalculate(vehicleID);
            }
            else if (e.Button == MouseButtons.Left)
            {
                if (_pathfinder.Squares[point.X, point.Y].ContentCode == SquareContent.Empty)
                {
                    /*
                     * 
                     * Turn an empty square into a wall on click.
                     * 
                     * */
                    _pathfinder.Squares[point.X, point.Y].ContentCode = SquareContent.Wall;
                    Recalculate(vehicleID);
                }
                else if (_pathfinder.Squares[point.X, point.Y].ContentCode == SquareContent.Wall)
                {
                    _pathfinder.Squares[point.X, point.Y].ContentCode = SquareContent.Empty;
                    Recalculate(vehicleID);
                }
            }
        }

        private void Recalculate(int vehicleID)
        {
            _pathfinder.ClearLogic();
            _pathfinder.Pathfind(vehicleID);
            _pathfinder.HighlightPath(vehicleID);
            _pathfinder.DrawBoard(boardControl1, vehicleID);
        }

        private void ReadMap(string fileName)
        {
            /*
             * 
             * Read in a map file.
             * 
             * */
            
            /*using (StreamReader reader = new StreamReader(fileName))
            {
                int lineNum = 0;
                string line;
                while ((line = reader.ReadLine()) != null)
                {
                    char[] parts = line.ToCharArray();
                    for (int i = 0; i < parts.Length && i < Pathfinder.gridSizeY; i++)
                    {
                        _pathfinder.Squares[i, lineNum].FromChar(parts[i]);
                    }
                    lineNum++;
                }
            }*/

            using (StreamReader reader = new StreamReader(fileName))
            {
                string line;
                int row = 0;
                while (true)
                {
                    line = reader.ReadLine();
                    if (line == null) break;

                    string[] parts;
                    parts = line.Split(',');

                    for (int col = 0; col < parts.Length; col++)
                    {
                        _pathfinder.Squares[col, row].ContentCode = Convert.ToInt32(parts[col]);
                    }

                    row++;
                }
            }
            
        }

        private void mapButton_Click(object sender, EventArgs e)
        {
            /*
             * 
             * Just deals with the UI.
             * 
             * */

            int vehicleID;
            vehicleID = Convert.ToInt32(tbAracKodu.Text);

            DialogResult result = openFileDialog1.ShowDialog();
            if (result == DialogResult.OK)
            {
                _pathfinder.ClearSquares();
                _pathfinder.ClearLogic();
                try
                {
                    ReadMap(openFileDialog1.FileName);
                    _pathfinder.Pathfind(vehicleID);
                    _pathfinder.HighlightPath(vehicleID);
                }
                catch
                {
                    toolStripStatusLabel1.Text = "IO Error";
                }
                finally
                {
                    _pathfinder.DrawBoard(boardControl1, vehicleID);
                }
            }
        }

        private void btnSaveMap_Click(object sender, EventArgs e)
        {
            DialogResult resultMap = saveFileDialog1.ShowDialog();
            if (resultMap == DialogResult.OK)
            {
                if (saveFileDialog1.FileName.Length == 0)
                    return;

                //FileStream fs = new FileStream(saveFileDialog1.FileName, FileMode.Create, FileAccess.Write);
                StreamWriter fs = new StreamWriter(saveFileDialog1.FileName);

                /*for (int y = 0; y < Pathfinder.gridSizeY; y++)
                {
                    string myline;
                    myline = "";

                    for (int x = 0; x < Pathfinder.gridSizeX; x++)
                    {
                        myline += _pathfinder.Squares[x, y].ToChar().ToString();
                    }
                    fs.WriteLine(myline);
                }*/

                for (int y = 0; y < Pathfinder.gridSizeY; y++)
                {
                    string myline;
                    myline = "";

                    for (int x = 0; x < Pathfinder.gridSizeX; x++)
                    {
                        myline += _pathfinder.Squares[x, y].ContentCode.ToString();
                        if (x < (Pathfinder.gridSizeX - 1))
                        {
                            myline += ",";
                        }
                    }

                    fs.WriteLine(myline);
                }

                fs.Close();
            }
        }

        private void btnShowButton_Click(object sender, EventArgs e)
        {
            int vehicleID;
            vehicleID = Convert.ToInt32(tbAracKodu.Text);

            List<Point> path;
            path = _pathfinder.HighlightPath(vehicleID);

            string pr = "";

            foreach (Point p in path)
            {
                pr = pr + p.ToString() + "\n";
            }

            MessageBox.Show(pr);

            pr = "";
            for (int i = 1; i < path.Count; i++)
            {
                Point movement;
                movement = Pathfinder.ExtractMovement(path[i - 1], path[i]);
                pr = pr + movement.ToString() + "\n";
            }

            MessageBox.Show(pr);
        }

        private void btnAracKonum_Click(object sender, EventArgs e)
        {
            int vehicleID;
            vehicleID = Convert.ToInt32(tbAracKodu.Text);

            Point point = new Point();
            point.X = Convert.ToInt32(tbAracKonumX.Text);
            point.Y = Convert.ToInt32(tbAracKonumY.Text);

            for (int row = 0; row < Pathfinder.gridSizeY; row++)
            {
                for (int col = 0; col < Pathfinder.gridSizeX; col++)
                {
                    if (_pathfinder.Squares[col, row].ContentCode == SquareContent.StartLocation(vehicleID))
                    {
                        _pathfinder.Squares[col, row].ContentCode = SquareContent.Empty;
                        break;
                    }
                }
            }
            _pathfinder.Squares[point.X, point.Y].ContentCode = SquareContent.StartLocation(vehicleID);
            Recalculate(vehicleID);
            return;
        }

        private void tbAracKodu_TextChanged(object sender, EventArgs e)
        {
            try
            {
                Recalculate(Convert.ToInt32(tbAracKodu.Text));
            }
            catch
            {
                // ignore
            }
        }

        private void startingPointToolStripMenuItem_Click(object sender, EventArgs e)
        {
            /*
             * 
             * Reposition the start location to the point clicked.
             * 
             * */
            int vehicleID;
            vehicleID = Convert.ToInt32(tbAracKodu.Text);
            Point point = boardControl1.Pos;
            for (int row = 0; row < Pathfinder.gridSizeY; row++)
            {
                for (int col = 0; col < Pathfinder.gridSizeX; col++)
                {
                    if (_pathfinder.Squares[col, row].ContentCode == SquareContent.StartLocation(vehicleID))
                    {
                        _pathfinder.Squares[col, row].ContentCode = SquareContent.Empty;
                        break;
                    }
                }
            }
            _pathfinder.Squares[point.X, point.Y].ContentCode = SquareContent.StartLocation(vehicleID);

            Recalculate(vehicleID);
        }

        private void finishingPointToolStripMenuItem_Click(object sender, EventArgs e)
        {
            /*
             * 
             * Reposition the finish location to the point clicked.
             * 
             * */
            int vehicleID;
            vehicleID = Convert.ToInt32(tbAracKodu.Text);
            Point point = boardControl1.Pos;
            for (int row = 0; row < Pathfinder.gridSizeY; row++)
            {
                for (int col = 0; col < Pathfinder.gridSizeX; col++)
                {
                    if (_pathfinder.Squares[col, row].ContentCode == SquareContent.FinishLocation(vehicleID))
                    {
                        _pathfinder.Squares[col, row].ContentCode = SquareContent.Empty;
                        break;
                    }
                }
            }
            if (point.X >= 0 && point.Y >= 0)
            {
                _pathfinder.Squares[point.X, point.Y].ContentCode = SquareContent.FinishLocation(vehicleID);
                Recalculate(vehicleID);
            }
        }

        private void wallToolStripMenuItem_Click(object sender, EventArgs e)
        {
            int vehicleID;
            vehicleID = Convert.ToInt32(tbAracKodu.Text);
            Point point = boardControl1.Pos;
            _pathfinder.Squares[point.X, point.Y].ContentCode = SquareContent.Wall;
            Recalculate(vehicleID);
        }

        private void emptinessToolStripMenuItem_Click(object sender, EventArgs e)
        {
            int vehicleID;
            vehicleID = Convert.ToInt32(tbAracKodu.Text);
            Point point = boardControl1.Pos;
            _pathfinder.Squares[point.X, point.Y].ContentCode = SquareContent.Empty;
            Recalculate(vehicleID);
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MessageBox.Show("First author: Sam Allen \nSecond authors: N. Engin Toklu, Onur Keskin", "About", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
    }
}
